package org.libspark.betweenas3
{
	import flash.display.*;
	import flash.events.*;
	import flash.geom.*;
	import flash.net.*;
	import flash.system.*;
	import flash.utils.clearTimeout;
	import flash.utils.setTimeout;
	
	import org.libspark.betweenas3.BetweenAS3;
	import org.libspark.betweenas3.easing.*;
	import org.libspark.betweenas3.events.TweenEvent;
	import org.libspark.betweenas3.tweens.ITween;
	import org.libspark.betweenas3.utils.BitmapUtil;
	
	/**
	 * iMac  特效
	 * 实例：
	 * var effect:MacEffect = new MacEffect($container,$display);
	 * effect.show(_x,_y); 显示
	 * effect.hide(_x,_y); 隐藏
	 * @author anjue
	 */
	public class MacEffect
	{
		
		private var IMG_W:int = 960;
		private var IMG_H:int = 560;
		private var SEGMENT:int = 10;
		private var _bmp:Bitmap;
		private var vertexs:Array;
		private var sprite:Sprite;
		private var isHide:Boolean = false;
		private var isShift:Boolean = false;
		
		private var _container:DisplayObjectContainer;
		
		private var _tweenList:Vector.<ITween> = new Vector.<ITween>();
		private var _timeOutList:Vector.<uint> = new Vector.<uint>();
		
		public function MacEffect($container:DisplayObjectContainer,$display:DisplayObject):void
		{
			_container = $container;
			init($display);
		}
		
		private function init($display:DisplayObject):void
		{
			IMG_W = $display.width;
			IMG_H = $display.height;
			if($display is Bitmap)
			{
				_bmp = $display as Bitmap;
			}else
			{
				_bmp = BitmapUtil.drawBitmap($display,true);
			}
			
			sprite = new Sprite();
			_container.addChild(sprite);
			vertexs = []
			for (var xx:int = 0; xx < SEGMENT; xx++) {
				vertexs[xx] = [];
				for (var yy:int = 0; yy < SEGMENT; yy++) {
					vertexs[xx][yy] = new Point(xx * IMG_W / SEGMENT, yy * IMG_H/SEGMENT);
				}
			}
		}
		
		public function show(_x:Number=100,_y:Number=100):void
		{
			var tweens:Array = [];
			var xx:int, yy:int, delay:Number;
			var px:Number = SEGMENT * (_x / IMG_W);
			var py:Number = SEGMENT * (_x / IMG_H);
			
			var max:Number = 0;
			for (xx = 0; xx < SEGMENT; xx++) {
				for (yy = 0; yy < SEGMENT; yy++) {
					vertexs[xx][yy] = new Point(px * IMG_W / SEGMENT, py * IMG_H / SEGMENT);
					delay = Math.sqrt((xx - px) * (xx - px) + (yy - py) * (yy - py))
					max = Math.max(max, delay);
				}
			}
			for (xx = 0; xx < SEGMENT; xx++) {
				for (yy = 0; yy < SEGMENT; yy++) {
					delay = (max - Math.sqrt((xx - px) * (xx - px) + (yy - py) * (yy - py))) / 40;
					tweens.push(
						BetweenAS3.delay(
							BetweenAS3.tween(vertexs[xx][yy], {
								x : xx * IMG_W / SEGMENT,
								y : yy * IMG_H / SEGMENT
							},null, delay + 0.05, Quad.easeOut),
							delay / 2
						)
					)
				}
			}
			clearAllEffectTimeOut();
			if(!_container.hasEventListener(Event.ENTER_FRAME))
				_container.addEventListener(Event.ENTER_FRAME,draw);
			var itw:ITween = BetweenAS3.parallelTweens(tweens);
			_tweenList.push(itw);
			itw.addEventListener(TweenEvent.COMPLETE,completeFun);
			itw.play();
		}
		
		public function hide(_x:Number=100,_y:Number=100):void
		{
			var tweens:Array = [];
			var xx:int, yy:int, delay:Number;
			var px:Number = SEGMENT * (_x / IMG_W);
			var py:Number = SEGMENT * (_y / IMG_H);
			
			for (xx = 0; xx < SEGMENT; xx++) {
				for (yy = 0; yy < SEGMENT; yy++) {
					vertexs[xx][yy] = new Point(xx * IMG_W / SEGMENT, yy * IMG_H/SEGMENT);
					delay = Math.sqrt((xx - px) * (xx - px) + (yy - py) * (yy - py)) / 40;
					
					tweens.push(
						BetweenAS3.delay(
							BetweenAS3.tween(vertexs[xx][yy], {
								x : px * IMG_W / SEGMENT,
								y : py * IMG_H / SEGMENT
							},null, delay, Cubic.easeIn),
							delay / 2
						)
					)
				}
			}
			clearAllEffectTimeOut();
			if(!_container.hasEventListener(Event.ENTER_FRAME))
				_container.addEventListener(Event.ENTER_FRAME,draw);
			var itw:ITween = BetweenAS3.parallelTweens(tweens);
			_tweenList.push(itw);
			itw.addEventListener(TweenEvent.COMPLETE,completeFun);
			itw.play();
		}
		
		private function completeFun(e:TweenEvent):void
		{
			var itw:ITween = e.currentTarget as ITween;
			itw.removeEventListener(TweenEvent.COMPLETE,completeFun);
			var index:int = _tweenList.indexOf(itw);
			if(index != -1)
			{
				_tweenList.splice(index,1);
			}
			if(_tweenList.length == 0)
			{
				var _t:uint = setTimeout(function ():void
				{
					_container.removeEventListener(Event.ENTER_FRAME,draw);
				},500);
				_timeOutList.push(_t);
			}
		}
		
		private function draw(e:Event = null):void
		{
			var vertices:Vector.<Number> = new Vector.<Number>();
			var indices:Vector.<int> = new Vector.<int>();
			var uvtData:Vector.<Number> = new Vector.<Number>();
			
			for (var xx:int = 0; xx < SEGMENT; xx++) {
				for (var yy:int = 0; yy < SEGMENT; yy++) {
					vertices[vertices.length] = vertexs[xx][yy].x
					vertices[vertices.length] = vertexs[xx][yy].y
					uvtData[uvtData.length] = xx / SEGMENT;
					uvtData[uvtData.length] = yy / SEGMENT;
				}
			}
			
			for (var i:int = 0; i < SEGMENT - 1; i++) {
				for (var j:int = 0; j < SEGMENT - 1; j++) {
					indices.push(i * SEGMENT + j, i * SEGMENT + j + 1, (i + 1) * SEGMENT + j);
					indices.push(i * SEGMENT + j + 1, (i + 1) * SEGMENT + 1 + j, (i + 1) * SEGMENT + j);
				}
			}
			
			var g:Graphics = sprite.graphics;
			g.clear();
			g.beginBitmapFill(_bmp.bitmapData);
			g.drawTriangles(vertices, indices, uvtData);
			g.endFill();
		}
		
		private function clearAllEffectTimeOut():void
		{
			while(_timeOutList.length>0)
			{
				var _t:uint = _timeOutList.pop();
				clearTimeout(_t);
			}
		}
		
		private function clearAllEffectTween():void
		{
			while(_tweenList.length>0)
			{
				var itw:ITween = _tweenList.pop();
				itw.removeEventListener(TweenEvent.COMPLETE,completeFun);
				itw.stop();
			}
		}
		
		public function destroy():void
		{
			_container.removeEventListener(Event.ENTER_FRAME,draw);
			clearAllEffectTimeOut();
			clearAllEffectTween();
		}
	}
}
